package storage

import (
	"fmt"
	"io"
	"mime/multipart"
	"path/filepath"
	"strings"
)

// Manager 存储管理器
type Manager struct {
	driver StorageDriver
	config *UploadConfig
}

// GetDriver 获取存储驱动
func (m *Manager) GetDriver() StorageDriver {
	return m.driver
}

// NewManager 创建存储管理器
func NewManager(driver StorageDriver, config *UploadConfig) *Manager {
	return &Manager{
		driver: driver,
		config: config,
	}
}

// UploadFile 通用文件上传
func (m *Manager) UploadFile(fileHeader *multipart.FileHeader, category string) (*FileInfo, error) {
	// 验证文件
	if err := m.validateFile(fileHeader); err != nil {
		return nil, err
	}

	// 打开文件读取内容
	src, err := fileHeader.Open()
	if err != nil {
		return nil, fmt.Errorf("打开上传文件失败: %w", err)
	}
	defer src.Close()

	// 读取文件内容并生成MD5文件名
	content, err := io.ReadAll(src)
	if err != nil {
		return nil, fmt.Errorf("读取文件内容失败: %w", err)
	}

	// 根据配置选择哈希算法
	hashAlgorithm := "sha256" // 默认使用SHA256
	if m.config != nil && m.config.HashAlgorithm != "" {
		hashAlgorithm = m.config.HashAlgorithm
	}

	var secureFilename, filename string

	if hashAlgorithm == "sha256" {
		// 首先尝试使用纯SHA256文件名检查是否已存在（去重）
		secureFilename = GenerateSecureFilenameWithSHA256(fileHeader.Filename, content)
		filename = GenerateFilenameWithSHA256(fileHeader.Filename, content)
	} else {
		// 使用MD5（向后兼容）
		secureFilename = GenerateSecureFilename(fileHeader.Filename, content)
		filename = GenerateFilename(fileHeader.Filename, content)
	}

	secureStoragePath := GeneratePath(category, secureFilename)

	if m.driver.Exists(secureStoragePath) {
		// 文件已存在，直接返回已有文件的URL
		url := m.driver.GetURL(secureStoragePath)
		return &FileInfo{
			OriginalName: fileHeader.Filename,
			StoredName:   secureFilename,
			Size:         fileHeader.Size,
			ContentType:  fileHeader.Header.Get("Content-Type"),
			Path:         secureStoragePath,
			URL:          url,
			Category:     category,
		}, nil
	}

	// 生成带时间戳和随机字符串的安全文件名
	storagePath := GeneratePath(category, filename)

	// 检查新文件名是否冲突（极低概率）
	if m.driver.Exists(storagePath) {
		// 如果仍然冲突，重新生成文件名
		for i := 0; i < 3; i++ {
			filename = GenerateFilename(fileHeader.Filename, content)
			storagePath = GeneratePath(category, filename)
			if !m.driver.Exists(storagePath) {
				break
			}
		}
	}

	// 使用内容创建新的Reader上传文件
	reader := strings.NewReader(string(content))
	url, err := m.driver.Upload(storagePath, reader, fileHeader.Filename)
	if err != nil {
		return nil, err
	}

	return &FileInfo{
		OriginalName: fileHeader.Filename,
		StoredName:   filename,
		Size:         fileHeader.Size,
		ContentType:  fileHeader.Header.Get("Content-Type"),
		Path:         storagePath,
		URL:          url,
		Category:     category,
	}, nil
}

// UploadImage 上传图片 (保持向后兼容)
func (m *Manager) UploadImage(fileHeader *multipart.FileHeader) (*FileInfo, error) {
	return m.UploadFile(fileHeader, "image")
}

// UploadAvatar 上传头像 (保持向后兼容)
func (m *Manager) UploadAvatar(fileHeader *multipart.FileHeader) (*FileInfo, error) {
	return m.UploadFile(fileHeader, "avatar")
}

// DeleteFile 删除文件
func (m *Manager) DeleteFile(path string) error {
	return m.driver.Delete(path)
}

// validateFile 验证文件
func (m *Manager) validateFile(fileHeader *multipart.FileHeader) error {
	// 检查文件大小
	if m.config.MaxSize > 0 && fileHeader.Size > m.config.MaxSize {
		return fmt.Errorf("文件大小超过限制，最大允许 %d 字节", m.config.MaxSize)
	}

	// 检查文件类型
	if len(m.config.AllowedTypes) > 0 {
		contentType := fileHeader.Header.Get("Content-Type")
		ext := strings.ToLower(filepath.Ext(fileHeader.Filename))
		
		allowed := false
		for _, allowedType := range m.config.AllowedTypes {
			if strings.Contains(contentType, allowedType) || ext == allowedType {
				allowed = true
				break
			}
		}
		
		if !allowed {
			return fmt.Errorf("不支持的文件类型，允许的类型: %v", m.config.AllowedTypes)
		}
	}

	return nil
}

// GetDefaultImageConfig 获取默认图片上传配置
func GetDefaultImageConfig() *UploadConfig {
	return &UploadConfig{
		AllowedTypes:  []string{"image/jpeg", "image/png", "image/gif", ".jpg", ".jpeg", ".png", ".gif"},
		MaxSize:       2 * 1024 * 1024, // 2MB
		PathPrefix:    "uploads",
		HashAlgorithm: "sha256", // 默认使用SHA256
	}
}

// GetDefaultAvatarConfig 获取默认头像上传配置
func GetDefaultAvatarConfig() *UploadConfig {
	return &UploadConfig{
		AllowedTypes:  []string{"image/jpeg", "image/png", ".jpg", ".jpeg", ".png"},
		MaxSize:       1 * 1024 * 1024, // 1MB
		PathPrefix:    "uploads",
		HashAlgorithm: "sha256", // 默认使用SHA256
	}
}
